use semver::Version;
-use core::{Dependency, Manifest, PackageId, SourceId, Target};
+use core::{Dependency, Manifest, PackageId, SourceId, Target, TargetKind};
use core::{Summary, Metadata, SourceMap};
use ops;
-use util::{CargoResult, Config, LazyCell, ChainError, internal, human};
+use util::{CargoResult, Config, LazyCell, ChainError, internal, human, lev_distance};
use rustc_serialize::{Encoder,Encodable};
/// Information about a package that is available somewhere in the file system.
pub fn generate_metadata(&self) -> Metadata {
self.package_id().generate_metadata()
}
+
+ pub fn find_closest_target(&self, target: &str, kind: TargetKind) -> Option<&Target> {
+ let targets = self.targets();
+
+ let matches = targets.iter().filter(|t| *t.kind() == kind)
+ .map(|t| (lev_distance(target, t.name()), t))
+ .filter(|&(d, _)| d < 4);
+ matches.min_by_key(|t| t.0).map(|t| t.1)
+ }
}
impl fmt::Display for Package {
Ok((packages, resolved_with_overrides))
}
+fn validate_target(package: &Package,
+ name: &str,
+ kind: TargetKind,
+ kind_str: &str) -> CargoResult<()> {
+ let target = package.targets().iter().find(|t: &&Target| {
+ t.name() == name && *t.kind() == TargetKind::Bin
+ });
+ if target.is_none() {
+ let suggestion = package.find_closest_target(name, kind);
+ match suggestion {
+ Some(s) => bail!("no {} target named `{}`\n\nDid you mean `{}`?",
+ kind_str, name, s.name()),
+ None => bail!("no {} target named `{}`", kind_str, name),
+ }
+ }
+
+ Ok(())
+}
+
pub fn compile_pkg<'a>(root_package: &Package,
source: Option<Box<Source + 'a>>,
options: &CompileOptions<'a>)
bail!("jobs must be at least 1")
}
+ if let CompileFilter::Only{bins, examples, ..} = *filter {
+ for bin in bins {
+ try!(validate_target(root_package, bin, TargetKind::Bin, "bin"));
+ }
+
+ for example in examples {
+ try!(validate_target(root_package, example, TargetKind::Example, "example"));
+ }
+ }
+
let (packages, resolve_with_overrides) = {
try!(resolve_dependencies(root_package, config, source, features,
no_default_features))
"#, error = ERROR, proj_dir = p.url())));
});
+test!(cargo_compile_with_filename{
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/a.rs", r#"
+ extern crate foo;
+ fn main() { println!("hello a.rs"); }
+ "#)
+ .file("examples/a.rs", r#"
+ fn main() { println!("example"); }
+ "#);
+
+ assert_that(p.cargo_process("build").arg("--bin").arg("bin.rs"),
+ execs().with_status(101).with_stderr(&format!("\
+{error} no bin target named `bin.rs`", error = ERROR)));
+
+ assert_that(p.cargo_process("build").arg("--bin").arg("a.rs"),
+ execs().with_status(101).with_stderr(&format!("\
+{error} no bin target named `a.rs`
+
+Did you mean `a`?", error = ERROR)));
+
+ assert_that(p.cargo_process("build").arg("--example").arg("example.rs"),
+ execs().with_status(101).with_stderr(&format!("\
+{error} no example target named `example.rs`", error = ERROR)));
+
+ assert_that(p.cargo_process("build").arg("--example").arg("a.rs"),
+ execs().with_status(101).with_stderr(&format!("\
+{error} no example target named `a.rs`
+
+Did you mean `a`?", error = ERROR)));
+});
+
test!(compile_path_dep_then_change_version {
let p = project("foo")
.file("Cargo.toml", r#"
sep = SEP)));
});
+test!(run_with_filename {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [project]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/lib.rs", "")
+ .file("src/bin/a.rs", r#"
+ extern crate foo;
+ fn main() { println!("hello a.rs"); }
+ "#)
+ .file("examples/a.rs", r#"
+ fn main() { println!("example"); }
+ "#);
+
+ assert_that(p.cargo_process("run").arg("--bin").arg("bin.rs"),
+ execs().with_status(101).with_stderr(&format!("\
+{error} no bin target named `bin.rs`", error = ERROR)));
+
+ assert_that(p.cargo_process("run").arg("--bin").arg("a.rs"),
+ execs().with_status(101).with_stderr(&format!("\
+{error} no bin target named `a.rs`
+
+Did you mean `a`?", error = ERROR)));
+
+ assert_that(p.cargo_process("run").arg("--example").arg("example.rs"),
+ execs().with_status(101).with_stderr(&format!("\
+{error} no example target named `example.rs`", error = ERROR)));
+
+ assert_that(p.cargo_process("run").arg("--example").arg("a.rs"),
+ execs().with_status(101).with_stderr(&format!("\
+{error} no example target named `a.rs`
+
+Did you mean `a`?", error = ERROR)));
+});
+
test!(either_name_or_example {
let p = project("foo")
.file("Cargo.toml", r#"